Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

DEX-1270 remove id from optionEditor #412

Merged
merged 7 commits into from
Jul 7, 2022

Conversation

Atticus29
Copy link
Contributor

@Atticus29 Atticus29 commented Jun 30, 2022

Pull request checklist:

  • Features and bugfixes should be PRed into the develop branch, not main

  • All text is internationalized

    • N/A
  • There are no linter errors

  • New features support all states (loading, error, etc)

    • N/A
  • Thanks for keeping it clean! Feel free to merge your own pull request after it has been approved - just use the "squash & merge" option.

This PR removes the unneccesary id attribute from custom filed options. This brings newly-created custom field options in line with the current behavior of migrated custom fields.
The removal of id here does not seem to affect the metadata cards for sightings or encounters.

It was decided that, because the end users will be exporting, bulk importing, and otherwise using these custom field options, they should be in control of what both the labels and values are (provided that these are unique - see DEX-1270 for that issue).

QA notes:

Old behavior when an admin tried to remove any multi-select custom field option:

Before deleting "Standing":
Screen Shot 2022-06-30 at 12 37 44 PM

After deleting "Standing":
Screen Shot 2022-06-30 at 12 34 14 PM
(i.e., they would all be removed)

New behavior after this PR gets merged:

Before deleting "Standing":
Screen Shot 2022-06-30 at 12 37 44 PM

After deleting "Standing":
Screen Shot 2022-06-30 at 12 37 52 PM

Other things to confirm:

  • Creating a new multi-select custom field and creating options works and persists without error
  • Editing (add/removing) options from the above works and persists without error
  • Creating a new single-select (a.k.a dropdown) custom field and creating options works and persists without error
  • Editing (add/removing) options from the above works and persists without error
  • Confirm that metadata cards for sightings or encounters on some old sightings page are not wonky as a result of this.

@Atticus29 Atticus29 marked this pull request as ready for review June 30, 2022 19:41
Emily-Ke
Emily-Ke previously approved these changes Jun 30, 2022
Copy link
Contributor

@Emily-Ke Emily-Ke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@Emily-Ke Emily-Ke dismissed their stale review July 1, 2022 18:42

Found a problem when creating the options

@@ -42,7 +41,7 @@ export default function OptionEditor({
flexDirection: 'column',
marginBottom: 12,
}}
key={option.id}
key={option.value}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Option values and/or labels cannot be guaranteed to be unique within this component. If a user clicks "Add Another Option" several times, each option looks exactly the same: [{ label: '', value: '' }, { label: '', value: '' }, // etc.]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, "value" is not a stable identifier for a key because whenever an option's value is updated, the key changes. This causes the value input to lose focus.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm...what would you recommend in this case? Just generate a uuid?

Copy link
Contributor Author

@Atticus29 Atticus29 Jul 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Option values and/or labels cannot be guaranteed to be unique within this component. If a user clicks "Add Another Option" several times, each option looks exactly the same: [{ label: '', value: '' }, { label: '', value: '' }, // etc.]

I think that this will at least be partially ameliorated by Jon's back end work on DEX-1270 (this makes me realize that I mis-typed and this whole FE PR is for ticket DEX-1120).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be partially ameliorated because we will be able to know that the values from the database are unique. However, while values are being added and edited within the dialog, it will always be possible for multiple value fields to be the same.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once the values from the database are unique, it might be sufficient to add a timestamp property to objects created on the frontend ie. { label, value, created: Date.now() }. obviously the backend objects wouldn't have these but you could use key={o?.created || o?.value}

Copy link
Contributor

@brmscheiner brmscheiner Jul 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, "value" is not a stable identifier for a key because whenever an option's value is updated, the key changes. This causes the value input to lose focus.

for this to be resolved we would need to make sure the value used in the keys was the backend value, not the frontend's input value that changes as typed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok... with the most recent changes, I believe that the only way that two options would have the same key would be if 1) they were migrated and 2) they had the same exact value.

I would argue that the behavior of deletion of any one of these resulting in the deletion of all of them is a feature rather than a bug, because it helps improve the usability of the product.

@Atticus29 Atticus29 force-pushed the DEX-1120-fix-option-delete-for-multi-select branch 2 times, most recently from aaf2d88 to 47e8dcb Compare July 6, 2022 17:11
@Atticus29 Atticus29 force-pushed the DEX-1120-fix-option-delete-for-multi-select branch from 47e8dcb to 77c5ee3 Compare July 6, 2022 17:14
>
{children}
</Button>
<Tooltip title={tooltiptext}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this makes things more complicated, but the Tooltip component shouldn't be rendered unless it is being used

option => !option?.value || !option?.label,
).length > 0
}
tooltiptext={
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be camelCase (tooltipText)

@Atticus29 Atticus29 force-pushed the DEX-1120-fix-option-delete-for-multi-select branch from 319b5df to 2ffec49 Compare July 6, 2022 22:29
@Emily-Ke Emily-Ke dismissed their stale review July 6, 2022 22:59

The code has been changed since the review.

Comment on lines 141 to 148
display = 'panel',
loading = false,
style,
disabled,
showTooltip = false,
tooltipText = '',
size,
...rest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anything that is being passed through can just be part of ...rest. I think you only need:

{    
  showTooltip = false,
  tooltipText = '',
  ...rest
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing everything else actually broke things. Curious.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see any errors with this:

const ButtonWithTooltip = function (
  {
    showTooltip = false,
    tooltipText = '',
    ...rest
  },
  ref,
) {
  if (showTooltip)
    return (
      <Tooltip title={tooltipText}>
        <span>
          <CoreForwardRef ref={ref} {...rest} />
        </span>
      </Tooltip>
    );
  else
    return (
      <CoreForwardRef ref={ref} {...rest} />
    );
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 Thank you. Addressed in 75e6ad4

Comment on lines 126 to 135
showTooltip
tooltipText={
displayedOptions.filter(
option => !option?.value || !option?.label,
).length > 0
? intl.formatMessage({
id: 'UNFINISHED_OPTIONS',
})
: ''
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the options are valid, there is no need for a Tool tip.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you're thinking here. Do you mean that it would be better to have a separate element when options are valid?

I can't pass null to a tooltip without weird behavior (it just shows an empty tooltip), but I can pass undefined. Is this what you mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in b2c0f77

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that showTooltip should be false. It that case tooltipText will not be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. Thanks. Addressed in ed875d1

Comment on lines 128 to 130
displayedOptions.filter(
option => !option?.value || !option?.label,
).length > 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth defining an areOptionsValid variable for clarity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in b2c0f77

@Atticus29 Atticus29 force-pushed the DEX-1120-fix-option-delete-for-multi-select branch from 5767ec6 to b2c0f77 Compare July 7, 2022 17:40
Comment on lines 29 to 32
filter(
displayedOptions,
option => !option?.value || !option?.label,
).length === 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some might be easier to read here.
https://lodash.com/docs/#some

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix in 0f31a48

option => !option?.value || !option?.label,
).length === 0;
const areAllValuesUnique =
uniq(map(displayedOptions, option => option?.value)).length ===
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uniqBy would let you skip the map
https://lodash.com/docs/#uniqBy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix in 0f31a48

flexDirection: 'column',
marginBottom: 12,
}}
key={optionIndex}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the index as the key feels dangerous. I agree that it works in this case though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was getting too complicated, and this really helped to simplify.

})}
);
},
[],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature for map does not have a third argument.
https://lodash.com/docs/#map

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WHY DO I KEEP DOING THIS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix in 0f31a48

@Atticus29 Atticus29 merged commit ce66873 into develop Jul 7, 2022
@Atticus29 Atticus29 deleted the DEX-1120-fix-option-delete-for-multi-select branch July 7, 2022 23:50
@Emily-Ke Emily-Ke mentioned this pull request Jul 9, 2022
4 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants